/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { Gesture as RNGesture, Directions, GestureType as RnGestureType } from 'react-native-gesture-handler';
import { Platform } from 'react-native';
import { GestureMethods } from '../src/factory';

const DIRECTION_MAP: Record<string, number> = {
  right: Directions.RIGHT,
  left: Directions.LEFT,
  up: Directions.UP,
  down: Directions.DOWN,
};

type GestureEvent = {
  nativeEvent: any;
};

function wrapGesture(baseGesture: RnGestureType): GestureMethods {
  const wrapper: Partial<GestureMethods> = {
    gesture: baseGesture,
    __gestureConfig: {},
  };

  const configMap: Record<string, string> = {
    minPointers: 'minPointers',
    minDistance: 'minDistance',
    direction: 'direction',
    minVelocity: 'minVelocity',
    numberOfTaps: 'numberOfTaps',
    minDuration: 'minDurationMs',
    minAngle: 'minAngle',
    repeat: 'repeat',
    onStart: 'onStart',
    onUpdate: 'onUpdate',
    onEnd: 'onEnd',
    onCancel: 'onCancel',
    onHover: 'onHover',
  };

  for (const method in configMap) {
    wrapper[method as keyof GestureMethods] = function (
      ...args: unknown[]
    ): Partial<GestureMethods> {
      if (method === 'onHover' && Platform.OS !== 'harmony') {
        // 非 Harmony 平台，onHover 不做任何操作
        return wrapper;
      }
      if (
        method === 'direction' &&
        typeof args[0] === 'string' &&
        Platform.OS !== 'harmony'
      ) {
        const directionArg = args[0].toLowerCase();
        args[0] = DIRECTION_MAP[directionArg] ?? args[0];
      }
      if (typeof baseGesture[method] === 'function') {
        baseGesture[method](...args);
      } else if (method.startsWith('on') && typeof args[0] === 'function') {
        const eventName = method.slice(2).toLowerCase();
        baseGesture[eventName]?.((e) => args[0]({ nativeEvent: e }));
      }
      return this;
    };
  }

  return wrapper as GestureMethods;
}

export const createNativeGesture = (type: string): GestureMethods => {
  const map: Record<string, any> = {
    pan: () => wrapGesture(RNGesture.Pan()),
    tap: () => wrapGesture(RNGesture.Tap()),
    longPress: () => wrapGesture(RNGesture.LongPress()),
    rotation: () => wrapGesture(RNGesture.Rotation()),
    pinch: () => wrapGesture(RNGesture.Pinch()),
    fling: () => wrapGesture(RNGesture.Fling()),
    hover: () => wrapGesture(RNGesture.Hover()),
  };
  return map[type]?.() || wrapGesture(RNGesture.Pan());
};
